package com.smart.web.thread;

import com.smart.common.utils.file.FileUtils;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Test {
    private static final Map<String, Process> processMap = new HashMap<>();
    private static final ExecutorService executorService = Executors.newFixedThreadPool(10); // 创建一个固定大小的线程池

    /**
     * 启动FFmpeg进程
     *
     * @param identifier 进程标识符
     * @param command FFmpeg命令数组
     */
    public static void startProcess(String identifier, String[] command) {
        ProcessBuilder builder = new ProcessBuilder(command);
        try {
            Process process = builder.start();
            processMap.put(identifier, process);

            // 捕获标准输出
            executorService.submit(() -> readStream(process.getInputStream(), "STDOUT"));
            // 捕获标准错误
            executorService.submit(() -> readStream(process.getErrorStream(), "STDERR"));

        } catch (IOException e) {
            throw new RuntimeException("Failed to start FFmpeg process", e);
        }
    }

    private static void readStream(InputStream inputStream, String type) {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(type + ": " + line);
            }
        } catch (IOException e) {
            System.err.println("Error reading " + type + " stream: " + e.getMessage());
        }
    }

    /**
     * 停止指定标识符的FFmpeg进程
     *
     * @param identifier 进程标识符
     * @param path 文件保存路径
     */
    public static void stopProcess(String identifier, String path) {
        Process process = processMap.get(identifier);
        if (process != null) {
            process.destroy();
            processMap.remove(identifier);
            System.out.println("已关闭FFmpeg进程：" + identifier);
        } else {
            System.out.println("未找到指定的FFmpeg进程：" + identifier);
        }
        System.err.println("删除生成的文件!");
        FileUtils.deleteDirectoryAllFiles(new File(path));
    }

    public static String[] getCommand(String ip, String port, String username, String password, String url, String savePath) {
        String[] command = new String[]{
                "ffmpeg",
                "-i", "rtsp://" + username + ":" + password + "@" + ip + ":" + port + url,  // 输入流的RTSP URL
                "-c:v", "libx264",
                "-c:a", "aac",
                "-hls_time", "10",
                "-hls_list_size", "2",
                "-hls_flags", "delete_segments",
                "-start_number", "0",
                "-f", "hls",
                savePath + "/output.m3u8"  // 输出HLS的.m3u8 playlist文件和ts分片
        };
        return command;
    }

    private static String getOutputPath(String name) {
        String path = null;
        if (System.getProperty("os.name").toLowerCase().contains("win")) {
            path = "D:\\Nginx\\html\\stream\\" + name;
        } else {
            path = "/path/to/nginx/html/stream/" + name; // 替换为实际的Linux路径
        }
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        return path;
    }

    public static void main(String[] args) {
        String ip = "192.168.88.118";
        String port = "554";
        String username = "admin";
        String password = "smart2024";
        String url = "/cam/realmonitor?channel=1&subtype=1";
        String[] command = getCommand(ip, port, username, password, url, getOutputPath("video"));

        // 启动FFmpeg进程
        executorService.submit(() -> Test.startProcess("a", command));

        // 停止FFmpeg进程
        executorService.submit(() -> {
            try {
                Thread.sleep(60000);
                Test.stopProcess("a", getOutputPath("video"));
                executorService.shutdown();
                try {
                    if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
                        executorService.shutdownNow();
                    }
                } catch (InterruptedException e) {
                    executorService.shutdownNow();
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.err.println("线程中断异常");
            }
        });
    }
}